/**
 ****************************************************************************************
 *
 * @file main.c
 *
 * @brief Main Entry of the application.
 *
 ****************************************************************************************
 */

#include "b6x.h"
#include "drvs.h"
#include "regs.h"
#include "dbg.h"


/*
 * DEFINES
 ****************************************************************************************
 */

#define PA_RET_SEE1           (2)
#define PA_RET_SEE2           (3)
#define PA_SOFT_PWM           (4)

#if (CTMR_USED)
#define PWC_TMR               (PWM_CTMR)
#define PWC_TMR_CH(n)         (PWM_CTMR_CH##n)
#define PWC_IRQc              (CTMR_IRQn)
#define PA_PWC_CH1            (15)
#define PA_PWC_CH2            (16)
#else
#define PWC_TMR               (PWM_ATMR)
#define PWC_TMR_CH(n)         (PWM_ATMR_CH##n##P)
#define PWC_IRQc              (ATMR_IRQn)
#define PA_PWC_CH1            (7)
#define PA_PWC_CH2            (8)
#endif


#define TIMER_INT_CH1_BIT     (0x02U)
#define TIMER_INT_CH2_BIT     (0x04U)
#define TIMER_INT_CH3_BIT     (0x08U)
#define TIMER_INT_CH4_BIT     (0x10U)
/*
 * FUNCTIONS
 ****************************************************************************************
 */

#if (CTMR_USED)
void CTMR_IRQHandler(void)
{
    uint32_t iflg = CTMR->IFM.Word;
    
    if (iflg & TIMER_INT_CH1_BIT) // ch1 interrupt
    {
        GPIO_DAT_SET(1 << PA_RET_SEE1);
        CTMR->ICR.CC1I = 1;
        GPIO_DAT_CLR(1 << PA_RET_SEE1 | (1 << PA_SOFT_PWM));
    }

    if (iflg & TIMER_INT_CH2_BIT) // ch2 interrupt
    {
        GPIO_DAT_SET(1 << PA_RET_SEE2 | (1 << PA_SOFT_PWM));
        CTMR->ICR.CC2I = 1;
        GPIO_DAT_CLR(1 << PA_RET_SEE2);
    }
    
}
#else
void ATMR_IRQHandler(void)
{
    uint32_t iflg = ATMR->IFM.Word;
    
    if (iflg & TIMER_INT_CH1_BIT) // ch1 interrupt
    {
        GPIO_DAT_SET(1 << PA_RET_SEE1);
        ATMR->ICR.CC1I = 1;
        GPIO_DAT_CLR(1 << PA_RET_SEE1 | (1 << PA_SOFT_PWM));
    }

    if (iflg & TIMER_INT_CH2_BIT) // ch2 interrupt
    {
        GPIO_DAT_SET(1 << PA_RET_SEE2 | (1 << PA_SOFT_PWM));
        ATMR->ICR.CC2I = 1;
        GPIO_DAT_CLR(1 << PA_RET_SEE2);
    }
}
#endif

static void pwcTest(void)
{
    // init PADs
    GPIO_DAT_CLR((1 << PA_RET_SEE1) | (1 << PA_RET_SEE2) | (1 << PA_SOFT_PWM) | (1 << PA_PWC_CH1) | (1 << PA_PWC_CH2));
    GPIO_DIR_SET((1 << PA_RET_SEE1) | (1 << PA_RET_SEE2) | (1 << PA_SOFT_PWM));
    GPIO_DIR_CLR((1 << PA_PWC_CH1) | (1 << PA_PWC_CH2));
    
    iom_ctrl(PA_PWC_CH1, IOM_PULLDOWN | IOM_INPUT | IOM_SEL_TIMER);
    iom_ctrl(PA_PWC_CH2, IOM_PULLDOWN | IOM_INPUT | IOM_SEL_TIMER);

    // init pwm timer
    pwm_init(PWC_TMR, 0, UINT16_MAX);
    
    // pwc_chnl config
    pwm_chnl_cfg_t chnl_cfg;
    
    chnl_cfg.duty = 0;
    chnl_cfg.ccmr = PWC_CCMR_MODE(1, 3, PWC_PSC0);
    chnl_cfg.ccer = PWC_CCER_NEGEDGE;
    pwm_chnl_set(PWC_TMR_CH(1), &chnl_cfg);
    chnl_cfg.ccer = PWC_CCER_POSEDGE;
    pwm_chnl_set(PWC_TMR_CH(2), &chnl_cfg);
    
    // start with SMCR.TS=5(TI1FP1), SMCR.SMS=4(reset mode)
    pwm_conf(PWC_TMR, 0x54, TIMER_INT_CH1_BIT | TIMER_INT_CH2_BIT); 
    pwm_start(PWC_TMR);
    
    // interrupt enable 
    NVIC_EnableIRQ(PWC_IRQc); 
    __enable_irq();
}

static void sysInit(void)
{
    // Todo config, if need
    
}

static void devInit(void)
{
    iwdt_disable();
    
    dbgInit();
    debug("PWC Test...\r\n"); 
}

int main(void)
{
    sysInit();
    devInit();
    
    pwcTest();
    
    while (1);
}
